package com.zhss.dfs.test;

import com.zhss.dfs.server.DataNodeConfig;
import com.zhss.dfs.server.NameNodeServiceActor;
import com.zhss.dfs.upgrade.NioServer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: filesystem
 * @description:
 * @author: Liu Weidong
 * @create: 2024-05-14 21:58
 **/
public class NioFileServer extends Thread {


    private Selector selector;

    public static void main(String[] args) {
        NioFileServer nioFileServer = new NioFileServer();
        nioFileServer.start();
    }


    private ByteBuffer fileBuffer;

    public NioFileServer() {
        ServerSocketChannel serverSocketChannel = null;
        try {
            selector = Selector.open();
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.bind(new InetSocketAddress(DataNodeConfig.DATANODE_HOSTNAME, DataNodeConfig.DATANODE_PORT));
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            System.out.println("dataNode-fileServer已经启动监听端口号" + DataNodeConfig.DATANODE_PORT + "...........................");
            while (true) {
                selector.select();
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    handleEvents(key);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void handleEvents(SelectionKey key) throws IOException {
        SocketChannel socketChannel = null;
        try {
            if (key.isAcceptable()) {
                ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
                socketChannel = serverSocketChannel.accept();
                socketChannel.configureBlocking(false);
                if (socketChannel != null) {
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                    System.out.println("接收到连接请求，注册读事件。。。。。。。。。。。");
                }
            } else if (key.isReadable()) {
                socketChannel = (SocketChannel) key.channel();
                handleRequest(socketChannel, key);
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (socketChannel != null) {
                socketChannel.close();
            }
        }
    }


    private void handleRequest(SocketChannel socketChannel, SelectionKey key) throws IOException {
        handleSendFileRequest(socketChannel, key);
    }
    /**
     * 处理上传文件的请求
     *
     * @param socketChannel
     * @throws IOException
     */
    private void handleSendFileRequest(SocketChannel socketChannel, SelectionKey key) throws IOException {
        // 向文件目录写入文件
        FileOutputStream outputStream = null;
        FileChannel fileChannel = null;
        try {
            ByteBuffer fileContentByteBuffer = null;
            fileContentByteBuffer =  fileBuffer == null ? ByteBuffer.allocate(368301) : fileBuffer;
            int read = socketChannel.read(fileContentByteBuffer);
            System.out.println("读取字节长度为：" + read);
            if (!fileContentByteBuffer.hasRemaining()) {
                outputStream = new FileOutputStream("D://a.jpg");
                fileChannel = outputStream.getChannel();
                fileChannel.position(fileChannel.size());
                // 文件内容已经全部读取完毕
                fileContentByteBuffer.rewind();
                fileChannel.write(fileContentByteBuffer);
                // 返回正确信息
                ByteBuffer outBuffer = ByteBuffer.wrap("SUCCESS".getBytes());
                socketChannel.write(outBuffer);
                // 移除本次文件上传的缓存
                key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
            } else {
                fileBuffer = fileContentByteBuffer;
            }

        } finally {
            if (fileChannel != null) {
                fileChannel.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}
